package com.ruoyi.business.controller;

import com.ruoyi.business.service.IFinancialOverviewService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.common.core.domain.vo.*;

import com.ruoyi.common.core.domain.export.FinancialOrderFoodExport;

import com.ruoyi.common.core.domain.vo.FinancialLeavePeople;
import com.ruoyi.common.core.domain.vo.FinancialOrderFoodVO;
import com.ruoyi.common.core.domain.vo.FinancialOverviewVO;

import com.ruoyi.common.core.page.TableDataInfo;

import com.ruoyi.common.utils.poi.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 财务概况
 */
@RestController
@RequestMapping("financialOverview")
public class FinancialOverviewController extends BaseController {

    @Autowired
    private IFinancialOverviewService financialOverviewService;
    /**
     * 运营概况
     */
    @GetMapping("/statistics")
    public AjaxResult getStatistics(@RequestParam Integer type, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        FinancialOverviewVO financialOverviewVO;
        LocalDate today = LocalDate.now();
        switch (type) {
            case 0:
                //昨日
                // 计算昨天的日期
                LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);
                // 昨天的开始时间
                LocalDateTime startOfYesterday =  LocalDateTime.of(yesterday, LocalTime.MIN);
                // 昨天的结束时间
                LocalDateTime endOfYesterday =  LocalDateTime.of(yesterday, LocalTime.MAX);
                financialOverviewVO = financialOverviewService.firstleve(startOfYesterday, endOfYesterday);
                break;
            case 1:
                LocalDateTime startOfToday = LocalDateTime.of(today, LocalTime.MIN);
                LocalDateTime endOfToday = LocalDateTime.of(today, LocalTime.MAX);
                //今日
                financialOverviewVO = financialOverviewService.firstleve(startOfToday, endOfToday);
                break;
            case 2:
                //本周
                LocalDateTime[] weekRange = getWeekStartAndEnd(today);
                financialOverviewVO = financialOverviewService.firstleve(weekRange[0], weekRange[1]);
                financialOverviewVO.setDiningLeaves( financialOverviewVO.getMealLeaves() );
                break;
            case 3:
                //本月
                LocalDateTime[] MonthRange = getMonthStartAndEnd(today);
                financialOverviewVO = financialOverviewService.firstleve(MonthRange[0], MonthRange[1]);
                financialOverviewVO.setDiningLeaves( financialOverviewVO.getMealLeaves() );
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    return AjaxResult.error("startDate 和 endDate 为必填项");
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                financialOverviewVO = financialOverviewService.firstleve(startDatesTime, endDatesTime);
                break;
            default:
                return AjaxResult.error("无效的类型。允许的值为 昨日、今日、本周、本月, 时间区间");
        }
        return AjaxResult.success(financialOverviewVO);
    }
    /**
     * 退款金额统计
     */
    @GetMapping(value = "/returnAmount")
    public AjaxResult returnAmount(@RequestParam Integer type, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        ChartDataBVO result = new ChartDataBVO();
        LocalDate today = LocalDate.now();
        switch (type) {
            case 2:
                //本周
                LocalDateTime[] weekRange = getWeekStartAndEnd(today);
                result = financialOverviewService.returnAmount(type,weekRange[0], weekRange[1]);
                break;
            case 3:
                //本月
                LocalDateTime[] MonthRange = getMonthStartAndEnd(today);
                result = financialOverviewService.returnAmount(type,MonthRange[0], MonthRange[1]);
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    //报错
                    break;
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                result = financialOverviewService.returnAmount(type,startDatesTime, endDatesTime);
                break;
            default:
                //报错
                break;
        }
        return AjaxResult.success(result);
    }
    /**
     * 退款统计
     */
    @GetMapping(value = "/returnPeople")
    public AjaxResult returnPeople(@RequestParam Integer type, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        ChartDataBVO result = new ChartDataBVO();
        LocalDate today = LocalDate.now();
        switch (type) {
            case 2:
                //本周
                LocalDateTime[] weekRange = getWeekStartAndEnd(today);
                result = financialOverviewService.returnPeople(type,weekRange[0], weekRange[1]);
                break;
            case 3:
                //本月
                LocalDateTime[] MonthRange = getMonthStartAndEnd(today);
                result = financialOverviewService.returnPeople(type,MonthRange[0], MonthRange[1]);
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    //报错
                    break;
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                result = financialOverviewService.returnPeople(type,startDatesTime, endDatesTime);
                break;
            default:
                //报错
                break;
        }
        return AjaxResult.success(result);
    }
    /**
     * 在线充值统计
     */
    @GetMapping(value = "/onLineRecharge")
    public AjaxResult returnLineChart(@RequestParam Integer type, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        ChartDataVO result = new ChartDataVO();
        LocalDate today = LocalDate.now();
        switch (type) {
            case 2:
                //本周
                LocalDateTime[] weekRange = getWeekStartAndEnd(today);
                result = financialOverviewService.secondleve(type,weekRange[0], weekRange[1]);
                break;
            case 3:
                //本月
                LocalDateTime[] MonthRange = getMonthStartAndEnd(today);
                result = financialOverviewService.secondleve(type,MonthRange[0], MonthRange[1]);
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    //报错
                    break;
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                result = financialOverviewService.secondleve(type,startDatesTime, endDatesTime);
                break;
            default:
                //报错
                break;
        }
        return AjaxResult.success(result);
    }

    /**
     * 学校订餐情况统计
     * @param type
     * @param startDate
     * @param endDate
     * @return
     */
    @GetMapping("/orderFood")
    public TableDataInfo orderFood(@RequestParam Integer type, @RequestParam(required = false) String schoolName,@RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        List<FinancialOrderFoodVO> financialOrderFoodVOList = new ArrayList<>();
        LocalDate today = LocalDate.now();
        switch (type) {
            case 2:
                //本周
                LocalDateTime[] weekRange = getWeekStartAndEnd(today);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,weekRange[0], weekRange[1]);
                break;
            case 3:
                //本月
                LocalDateTime[] MonthRange = getMonthStartAndEnd(today);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,MonthRange[0], MonthRange[1]);
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    //报错
                    break;
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,startDatesTime, endDatesTime);
                break;
            default:
                //报错
                break;
        }
        return getDataTable(financialOrderFoodVOList);
    }

    /**
     * 导出
     * @param response
     * @param type
     * @param schoolName
     * @param startDate
     * @param endDate
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestParam Integer type, @RequestParam(required = false) String schoolName,@RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate)
    {
        List<FinancialOrderFoodVO> financialOrderFoodVOList = new ArrayList<>();
        LocalDate today = LocalDate.now();
        switch (type) {
            case 2:
                //本周
                // 本周开始时间（默认周一作为一周开始）
                LocalDateTime startOfWeek = LocalDateTime.of(today.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)), LocalTime.MIN);
                // 本周结束时间（周日作为一周结束）
                LocalDateTime endOfWeek = LocalDateTime.of(today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)), LocalTime.MIN);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,startOfWeek, endOfWeek);
                break;
            case 3:
                //本月
                // 本月开始时间
                LocalDateTime startOfMonth = LocalDateTime.of(today.withDayOfMonth(1), LocalTime.MIN);
                // 本月结束时间，需要找到下个月的第一天，然后减一天
                LocalDateTime endOfMonth = LocalDateTime.of(today.withDayOfMonth(today.getMonth().length(today.isLeapYear())), LocalTime.MIN);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,startOfMonth, endOfMonth);
                break;
            case 4:
                //时间区间
                if (startDate == null || endDate == null) {
                    //报错
                    break;
                }
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate startDates = LocalDate.parse(startDate, formatter);
                LocalDateTime startDatesTime = startDates.atStartOfDay();
                LocalDate endDates = LocalDate.parse(endDate, formatter);
                LocalDateTime endDatesTime = endDates.plusDays(1).atStartOfDay().minusSeconds(1);
                financialOrderFoodVOList = financialOverviewService.orderFood(schoolName,startDatesTime, endDatesTime);
                break;
            default:
                //报错
                break;
        }
        ExcelUtil<FinancialOrderFoodExport> util = new ExcelUtil<FinancialOrderFoodExport>(FinancialOrderFoodExport.class);
        List<FinancialOrderFoodExport> list2 = financialOrderFoodVOList.stream()
                .map(w -> {
                    FinancialOrderFoodExport financialOrderFoodExport = new FinancialOrderFoodExport();
                    BeanUtils.copyProperties(w, financialOrderFoodExport);
                    return financialOrderFoodExport;
                }).collect( Collectors.toList());
        util.exportExcel(response, list2, "订餐信息统计");
    }
    /**
     * 请假人员
     */
    @GetMapping("/leavePeople")
    public TableDataInfo leavePeople(@RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) {
        List<FinancialLeavePeople> financialLeavePeoples = financialOverviewService.leavePeople(startDate, endDate);
        return getDataTable(financialLeavePeoples);
       }


       //获取本周
       public static LocalDateTime[] getWeekStartAndEnd(LocalDate date) {
           LocalDateTime startOfWeek = LocalDateTime.of(date.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY)), LocalTime.MIN);
           LocalDateTime endOfWeek = LocalDateTime.of(date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)), LocalTime.MIN);
           return new LocalDateTime[]{startOfWeek, endOfWeek};
       }
    //获取本月
    public static LocalDateTime[] getMonthStartAndEnd(LocalDate date) {
        LocalDateTime startOfMonth = LocalDateTime.of(date.withDayOfMonth(1), LocalTime.MIN);
        LocalDateTime endOfMonth = LocalDateTime.of(date.withDayOfMonth(date.getMonth().length(date.isLeapYear())), LocalTime.MIN);
        return new LocalDateTime[]{startOfMonth, endOfMonth};
    }
}
